<template>
  <div>
    <el-form
      ref="form"
      label-position="top"
      :model="container"
      :disabled="readonly"
    >
      <div v-for="(item, idx) in envUIList" :key="idx" class="env-row-item">
        <el-select
          v-model="item.type"
          style="max-width: 8rem"
          @change="t => onEnvTypeChanged(item, t)"
        >
          <el-option
            v-for="opt in uiState.type_list"
            :key="opt.id"
            :label="opt.label"
            :value="opt.id"
          />
        </el-select>

        <el-input v-model="item.refSrc.name" placeholder="Key" />
        <el-input
          v-if="item.type === 'KeyValue'"
          v-model="item.refSrc.value"
          placeholder="Value"
        />

        <el-select
          v-if="item.type === 'ConfigMap'"
          v-model="item.refSrc.valueFrom.configMapKeyRef.name"
          placeholder="请选择使用的资源"
          @change="name => onSourceChanged(item, name)"
        >
          <el-option
            v-for="opt in configMapSelections"
            :key="opt.metadata.name"
            :label="opt.metadata.name"
            :value="opt.metadata.name"
          />
        </el-select>

        <el-select
          v-if="item.type === 'ConfigMap'"
          v-model="item.refSrc.valueFrom.configMapKeyRef.key"
          placeholder="资源中的Key"
        >
          <el-option
            v-for="key in item.refKeys"
            :key="key"
            :label="key"
            :value="key"
          />
        </el-select>

        <el-select
          v-if="item.type === 'Secret'"
          v-model="item.refSrc.valueFrom.secretKeyRef.name"
          placeholder="请选择使用的资源"
          @change="name => onSourceChanged(item, name)"
        >
          <el-option
            v-for="opt in secretSelections"
            :key="opt.metadata.name"
            :label="opt.metadata.name"
            :value="opt.metadata.name"
          />
        </el-select>

        <el-select
          v-if="item.type === 'Secret'"
          v-model="item.refSrc.valueFrom.secretKeyRef.key"
          placeholder="资源中的Key"
        >
          <el-option
            v-for="key in item.refKeys"
            :key="key"
            :label="key"
            :value="key"
          />
        </el-select>

        <el-button circle size="small" icon="Delete" />
      </div>

      <el-button @click="onHandleAddEnv">
        {{ $t("commons.button.add") }}{{ $t("business.workload.variable") }}
      </el-button>
    </el-form>
  </div>
</template>

<script setup lang="ts">
import KoDataItem from "@/views/domain/kubeHud/views/components/ko-data-item/index.vue";
import {
  ConfigMap,
  Container,
  EnvVar,
  EnvVarSource,
  Secret,
  useK8SApi
} from "../../../api/k8s";
import { computed, onMounted, reactive, ref } from "vue";
import { objectToList } from "../../../utils";

const { configMapRepo, secretRepo } = useK8SApi();

type Prop = {
  readonly?: boolean;
  namespace?: string;
  secretList?: Secret[];
  configMapList?: ConfigMap[];
};

const props = withDefaults(defineProps<Prop>(), {
  readonly: false
});

const container = defineModel<Container>("container");

const configMapSelections = ref<ConfigMap[]>(props.configMapList ?? []);
const reloadConfigMap = async () => {
  configMapRepo
    .getConfigMap({ namespace: props.namespace })
    .then(({ items }) => {
      if (items) {
        configMapSelections.value = items;
      }
    });
};

const secretSelections = ref<Secret[]>(props.secretList ?? []);
const reloadSecret = async () => {
  secretRepo.getSecret({ namespace: props.namespace }).then(({ items }) => {
    if (items) {
      secretSelections.value = items;
    }
  });
};

type EnvUIType = "KeyValue" | "Resource" | "Secret" | "ConfigMap" | "Field";

const parseEnvType = (env: EnvVar): EnvUIType | undefined => {
  if (!env.valueFrom) {
    return "KeyValue";
  }
  if (env.valueFrom.configMapKeyRef) {
    return "ConfigMap";
  } else if (env.valueFrom.secretKeyRef) {
    return "Secret";
  } else if (env.valueFrom.resourceFieldRef) {
    return "Resource";
  } else if (env.valueFrom.fieldRef) {
    return "Field";
  }
};

const uiState = reactive({
  resource_value_list: [
    "limits.cpu",
    "limits.memory",
    "requests.cpu",
    "requests.memory"
  ],
  type_list: [
    { id: "KeyValue", label: "自定义" },
    { id: "ConfigMap", label: "来自数据字典" },
    { id: "Secret", label: "来自保密字典" }
  ]
  // type_list: [
  //   "Key/Value Pair",
  //   "PodField",
  //   "Resource",
  //   "ConfigMap key",
  //   "Secret",
  //   "Secret",
  //   "ConfigMap",
  //   "Field"
  // ]
});

type EnvUIItem = {
  type: EnvUIType;
  namespace?: string;

  refKeys?: string[]; // 引用资源的key列表

  refSrc?: EnvVar;
};

const envUIList = ref<EnvUIItem[]>([]);
const reloadEnvUIList = () => {
  envUIList.value = container.value.env?.map(e => {
    return {
      type: parseEnvType(e) ?? "KeyValue",
      namespace: props.namespace,
      refSrc: e
    };
  });
};

const onDeleteEnv = (index: number) => {
  const envItem = envUIList.value[index];
  envUIList.value.splice(index, 1);
};

const onHandleAddEnv = () => {
  const envVar: EnvVar = {};

  container.value.env && container.value.env.push(envVar);

  envUIList.value.push({
    type: "KeyValue",
    namespace: props.namespace,
    refSrc: envVar
  });
};

const onEnvTypeChanged = (envItem: EnvUIItem, type: EnvUIType) => {
  switch (type) {
    case "KeyValue":
      delete envItem.refSrc.valueFrom;
      break;
    case "ConfigMap":
      const initCfg = envItem.refSrc.valueFrom?.configMapKeyRef ?? {};
      envItem.refSrc.valueFrom = { configMapKeyRef: initCfg };
      break;
    case "Secret":
      const initSecret = envItem.refSrc.valueFrom?.secretKeyRef ?? {};
      envItem.refSrc.valueFrom = { secretKeyRef: initSecret };
      break;
  }
};

const onSourceChanged = (envItem: EnvUIItem, sourceName: string) => {
  console.log("onSourceChanged", envItem, sourceName);
  switch (envItem.type) {
    case "ConfigMap":
      const cfgIdx = configMapSelections.value.findIndex(
        e =>
          e.metadata.name === sourceName &&
          e.metadata.namespace === props.namespace
      );
      if (cfgIdx >= 0) {
        onConfigMapChanged(envItem, configMapSelections.value[cfgIdx]);
      }
      break;
    case "Secret":
      const secretIdx = secretSelections.value.findIndex(
        e =>
          e.metadata.name === sourceName &&
          e.metadata.namespace === props.namespace
      );
      if (secretIdx >= 0) {
        onSecretChanged(envItem, secretSelections.value[secretIdx]);
      }
      break;
  }
};

const onConfigMapChanged = (envItem: EnvUIItem, cfg: ConfigMap) => {
  if (envItem) {
    envItem.refSrc.valueFrom.configMapKeyRef.name = cfg.metadata.name;
  }
  envItem.refKeys = Object.keys(cfg.data ?? {});
};

const onSecretChanged = (envItem: EnvUIItem, secret: Secret) => {
  if (envItem.refSrc) {
    envItem.refSrc.valueFrom.secretKeyRef.name = secret.metadata.name;
  }

  envItem.refKeys = Object.keys(secret.data ?? {});
};

onMounted(() => {
  reloadEnvUIList();
  if (!props.configMapList || props.configMapList.length === 0) {
    reloadConfigMap();
  }

  if (!props.secretList || props.secretList.length === 0) {
    reloadSecret();
  }
});
</script>

<style lang="scss" scoped>
.env-row-item {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
  border: var(--el-border);
  padding: 5px;
  background-color: var(--el-border-color);
}
</style>
